﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;

namespace CalcSharp.Core.Containers
{
    public class Array2D<Type>
    {
        Type[] data;
        int rows, cols;

        public Array2D(int Rows, int Columns)
        {
            if (Rows < 0) throw new ArgumentException("Rows must be a positive number");
            if (Columns < 0) throw new ArgumentException("Columns must be a positive number");
            this.rows = Rows;
            this.cols = Columns;
            this.data = new Type[Rows * Columns];
        }

        public Array2D(Type[,] source)
        {
            this.rows = source.GetLength(0);
            this.cols = source.GetLength(1);
            this.data = new Type[rows * cols];
            for (int i = 0; i < rows; i++)
            {
                for (int j = 0; j < cols; j++)
                {
                    this.data[j * rows + i] = source[i, j];
                }
            }
        }

        public void InsertArrayAsRow(Type[] Array, int Rowindex)
        {
            int limit = this.Columns;
            if (Rowindex > this.Rows || Rowindex < 0) throw new ArgumentException("Rowindex must be in range: [0 -> rows count]");
            if (Array.Length <= this.Columns) limit = Array.Length;
            for (int i = 0; i < limit; i++) this[Rowindex, i] = Array[i];
        }

        public void InsertArrayAsColumn(Type[] Array, int Columnindex)
        {
            int limit = this.Rows;
            if (Columnindex > this.Columns || Columnindex < 0) throw new ArgumentException("Columnindex must be in range: [0 -> columns count]");
            if (Array.Length <= this.Rows) limit = Array.Length;
            for (int i = 0; i < limit; i++) this[i, Columnindex] = Array[i];
        }

        public Type this[int Row, int Column]
        {
            get { return data[Column * rows + Row]; }
            set { data[Column * rows + Row] = value; }
        }

        public int Rows
        {
            get { return rows; }
        }

        public int Columns
        {
            get { return cols; }
        }

        public int Length
        {
            get { return cols * rows; }
        }

        public Type[,] ToArray()
        {
            Type[,] array = new Type[this.rows, this.cols];
            for (int i = 0; i < this.cols; i++)
            {
                for (int j = 0; j < this.rows; i++)
                {
                    array[i, j] = data[j * rows + i];
                }
            }
            return array;
        }
    }
}
